<template>
  <div id="dialog-form">
    <HyDialog
      :title="title"
      v-model="dialogVisible"
      :width="550"
      :top="config.top || '15vh'"
      @closed="closed"
    >
      <HyForm
        :disabled="disabled"
        :model="forms"
        :rules="rules"
        ref="ruleFormDialog"
        label-position="right"
        label-width="auto"
      >
        <slot v-for="item in config.form" :key="item.key" :name="item.key" :row="item">
          <HyFormItem :label="item.label" :prop="item.key" v-if="!item.hide">
            <template v-if="item.type == 'select'">
              <HySelect
                :disabled="item.disabled"
                v-if="item.remote === true"
                v-model="forms[item.key]"
                :multiple="item.multiple"
                :placeholder="item.placeholder || '请选择'"
                :loading="selectOptions[item.key].remoteLoading"
                :remote-method="remoteMethod(item.key)"
                filterable
                remote
              >
                <HyOption
                  v-for="opt in selectOptions[item.key].list"
                  :key="opt.value"
                  :label="opt.label"
                  :value="opt.value"
                ></HyOption>
              </HySelect>
              <HySelect
                :disabled="item.disabled"
                :multiple="item.multiple"
                v-else
                v-model="forms[item.key]"
                :placeholder="item.placeholder || '请选择'"
              >
                <HyOption
                  v-for="opt in item.options"
                  :key="opt.value"
                  :label="opt.label"
                  :value="opt.value"
                ></HyOption>
              </HySelect>
            </template>
            <template v-else-if="item.commentsName === 'datePicker'">
              <HyDatePicker
                :disabled="item.disabled"
                v-model="forms[item.key]"
                :type="item.type"
                :placeholder="item.placeholder || '请选择'"
                :format="item.format || 'YYYY-MM-DD'"
                :value-format="item.format || 'YYYY-MM-DD'"
                :start-placeholder="item.startPlaceholder || '请选择开始日期'"
                :end-placeholder="item.endPlaceholder || '请选择结束日期'"
                :disabledDate="item.disabledDate || ''"
                :range-separator="item.disabledDate || '至'"
                :shortcuts="item.shortcuts || []"
              ></HyDatePicker>
            </template>
            <template v-else-if="item.commentsName === 'timeSelect'">
              <HyTimeSelect
                :disabled="item.disabled"
                v-model="forms[item.key]"
                :start="item.start"
                :step="item.step"
                :end="item.end"
                :placeholder="item.placeholder || '请选择'"
              ></HyTimeSelect>
            </template>
            <template v-else-if="item.type == 'switch'">
              <HySwitch :disabled="item.disabled" v-model="forms[item.key]"></HySwitch>
            </template>
            <template v-else-if="item.type == 'radio'">
              <HyRadioGroup v-model="forms[item.key]" :disabled="item.disabled">
                <HyRadio
                  :disabled="item.disabled"
                  v-for="item in item.options"
                  :key="item.value"
                  :label="item.value"
                >
                  {{ item.label }}
                </HyRadio>
              </HyRadioGroup>
            </template>
            <template v-else-if="item.type == 'checkbox'">
              <HyCheckboxGroup v-model="forms[item.key]" :disabled="item.disabled">
                <HyCheckbox
                  :disabled="item.disabled"
                  v-for="item in item.options"
                  :key="item.value"
                  :label="item.value"
                >
                  {{ item.label }}
                </HyCheckbox>
              </HyCheckboxGroup>
            </template>
            <template v-else-if="item.type == 'treeselect'">
              <HyTreeselect
                v-model="forms[item.key]"
                :dataAdaptiveMap="item.dataAdaptiveMap"
                :placeholder="item.placeholder || '请选择'"
                :treeselectList="item.reeselectData"
                :disabled="item.disabled"
              ></HyTreeselect>
            </template>
            <template v-else>
              <HyInput
                :disabled="item.disabled"
                @input="inputLimiting(item.key, item.handlerLimiting)"
                v-model.trim="forms[item.key]"
                :maxlength="item.maxlength"
                :type="item.type"
                :placeholder="item.placeholder || '请选择'"
              ></HyInput>
            </template>
          </HyFormItem>
        </slot>
      </HyForm>
      <template #footer>
        <span class="dialog-footer">
          <HyButton @click="close()">{{ disabled ? "关 闭" : "取 消" }}</HyButton>
          <HyButton
            v-show="!disabled"
            type="primary"
            @click="handlerSubmit()"
            :loading="loading"
          >
            {{ loading ? "保存中..." : "确定" }}
          </HyButton>
        </span>
      </template>
    </HyDialog>
  </div>
</template>

<script>
import {
	ElButton,
	ElDialog,
	ElForm,
	ElFormItem,
	ElSelect,
	ElOption,
	ElDatePicker,
	ElTimeSelect,
	ElInput,
	ElSwitch,
	ElRadioGroup,
	ElRadio,
	ElCheckbox,
	ElCheckboxGroup
} from 'element-plus';
import {
	reactive,
	toRefs,
	onMounted,
	getCurrentInstance,
	computed,
	watch,
	nextTick
} from 'vue';
import { CREATE, UPDATE, DELETE, QUERY } from '@/utils/Const';
import HyTreeselect from '@/components/CommonTreeselectV2';
export default {
	components : {
		HyButton : ElButton,
		HyDialog : ElDialog,
		HyForm : ElForm,
		HyFormItem : ElFormItem,
		HySelect : ElSelect,
		HyOption : ElOption,
		HyDatePicker : ElDatePicker,
		HyTimeSelect : ElTimeSelect,
		HyInput : ElInput,
		HySwitch : ElSwitch,
		HyRadioGroup : ElRadioGroup,
		HyRadio : ElRadio,
		HyCheckbox : ElCheckbox,
		HyCheckboxGroup : ElCheckboxGroup,
		HyTreeselect : HyTreeselect
	},
	props : {
		modelValue : {
			type : Object,
			required : true
		},
		config : {
			type : Object
		}
	},
	setup (ctx, context) {
		let ruleForm = null;
		let Instance = getCurrentInstance().proxy;
		// eslint-disable-next-line vue/no-setup-props-destructure
		let config = ctx.config;
		let state = reactive({
			loading : false,
			disabled : config.disabled,
			dialogVisible : config.dialogVisible,
			forms : {},
			rules : {},
			selectOptions : {}
		});

		// 标题
		let title = computed(() => {
			let type = config.type.toUpperCase();
			if (type.includes(CREATE)) {
				return '新增';
			}
			if (type.includes(DELETE)) {
				return '修改';
			}
			if (type.includes(UPDATE)) {
				return '修改';
			}
			if (type.includes(QUERY)) {
				return '查看';
			}
			return '';
		});

		let open = (params) => {
			config = params;
			state.dialogVisible = true;
			state.disabled = params.disabled;
			nextTick(() => {
				ruleForm = Instance.$refs['ruleFormDialog'];
			});
			init();
		};
		// 关闭
		let close = () => {
			ruleForm.resetFields();
			state.dialogVisible = false;
		};

		// 组件关闭后自动销毁组件
		let closed = () => {
			ruleForm.resetFields();
			config.close && config.close();
		};

		onMounted(() => {
			nextTick(() => {
				ruleForm = Instance.$refs['ruleFormDialog'];
			});
		});

		let init = () => {
			config.form.forEach((item) => {
				// 默认值
				state.forms[item.key] = item.defaultValue;
				// 组装验证器
				state.rules[item.key] = item.rules;
				// 远程搜索列表映射
				if (item.remote) {
					state.selectOptions[item.key] = {
						remoteLoading : false,
						list : []
					};
				}
				// checkbox
				if (item.defaultValue !== undefined && item.type === 'checkbox') {
					state.forms[item.key] = [];
				}
				// select 多选
				if (item.defaultValue !== undefined && item.type === 'select' && item.multiple) {
					state.forms[item.key] = [];
				}
				// 回显
				if (config.data && config.data[item.key] !== undefined) {
					let v = config.data[item.key];
					if (item.type === 'checkbox') {
						v = Array.isArray(v) ? v : [];
					}
					state.forms[item.key] = v;
				}
			});
			context.emit('update:modelValue', state.forms);
		};
		init();
		// 提交
		let handlerSubmit = () => {
			ruleForm.validate(async (valid) => {
				if (valid) {
					state.loading = true;
					let params = {};
					Object.keys(state.forms).forEach((key) => {
						if (
							state.forms[key] !== '' &&
              state.forms[key] !== 'null' &&
              state.forms[key] !== 'undefined' &&
              state.forms[key] !== null &&
              state.forms[key] !== undefined
						) {
							params[key] = state.forms[key];
						}
					});

					await config.handlerSubmit(params);
					state.loading = false;
					close();
				}
			});
		};

		// 远程搜索
		let remoteMethod = (key) => {
			let res = config.form.find((item) => item.key === key);
			return async (query) => {
				if (query !== '') {
					state.selectOptions[key].remoteLoading = true;
					state.selectOptions[key].list = await res.getOptions();
					state.selectOptions[key].remoteLoading = false;
				} else {
					state.selectOptions[key].list = [];
					state.selectOptions[key].remoteLoading = false;
				}
			};
		};

		// 输入限制
		let inputLimiting = (key, callback) => {
			if (callback) {
				state.forms[key] = callback(state.forms[key]);
			}
		};

		watch(state.forms, () => {
			context.emit('update:modelValue', state.forms);
		});

		return {
			open,
			title,
			inputLimiting,
			close,
			remoteMethod,
			handlerSubmit,
			closed,
			...toRefs(state)
		};
	}
};
</script>

<style lang="scss">
#dialog-form {
  .el-form-item__content,
  .el-select,
  .el-input {
    width: 380px !important;
    display: inline-block !important;
    margin-left: 0px !important;
  }
}
</style>
